import { format, isEmpty } from '@/utils/func.js'

let emailReg = /^[A-Za-z\d]+([-_.][A-Za-z\d]+)*@([A-Za-z\d]+[-.])+[A-Za-z\d]{2,4}$/
// 手机
let phoneReg = /^[1][3,4,5,6,7,8,9][0-9]{9}$/
// 电话 + 手机
let telephoneReg = /(^(0\d{2,3}-?)?\d{7,8})$|(^[1][3,4,5,6,7,8,9][0-9]{9}$)|^(400|800)\d{7}$/
// 协议编号
let protocolCodeReg = /^[0-9a-zA-Z]*$/

let regId = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/

let uscc = /^[0-9a-zA-Z]{13}$|^[0-9a-zA-Z]{15}$|^[0-9a-zA-Z]{18}$/

let url = /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/

const validators = {
  rules () {
    return { emailReg, phoneReg, telephoneReg, regId, uscc, url }
  },
  // 基本类型长度校验
  range (rule, value, callback) {
    var len = typeof rule.len === 'number'
    var min = typeof rule.min === 'number'
    var max = typeof rule.max === 'number' // 正则匹配码点范围从U+010000一直到U+10FFFF的文字（补充平面Supplementary Plane）
    var lenMessage = rule.msg || '请输入%s个字符'
    var mixMessage = rule.msg || '请输入不少于%s个字符'
    var maxMessage = rule.msg || '请输入不超过%s个字符'
    var rangeMessage = rule.msg || '请输入最小%s个,最大%s个字符'

    var spRegexp = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g
    var val = value
    var key = null
    var num = typeof value === 'number'
    var str = typeof value === 'string'
    var arr = Array.isArray(value)

    if (num) {
      key = 'number'
    } else if (str) {
      key = 'string'
    } else if (arr) {
      key = 'array'
    }

    if (!key) {
      callback()
      return
    }

    if (arr) {
      val = value.length
    }
    if (str) {
      // 处理码点大于U+010000的文字length属性不准确的bug，如"𠮷𠮷𠮷".lenght !== 3
      val = value.replace(spRegexp, '_').length
    }
    if (len) {
      if (val !== rule.len) {
        callback(new Error(format(lenMessage, rule.len)))
      } else {
        callback()
      }
    } else if (min && !max && val < rule.min) {
      callback(new Error(format(mixMessage, rule.min)))
    } else if (max && !min && val > rule.max) {
      callback(new Error(format(maxMessage, rule.max)))
    } else if (min && max && (val < rule.min || val > rule.max)) {
      callback(new Error(format(rangeMessage, rule.min, rule.max)))
    } else {
      callback()
    }
  },
  // 邮箱的验证规则
  validateEmail (rule, value, callback) {
    if (!isEmpty(value)) {
      if (!emailReg.test(value)) {
        callback(new Error('邮箱格式不正确'))
      } else {
        callback()
      }
    } else {
      callback()
    }
  },

  // 电话 + 手机的验证
  validateTelephone (rule, value, callback) {
    if (!isEmpty(value)) {
      if (!telephoneReg.test(value)) {
        callback(new Error('电话号码格式不正确'))
      } else {
        callback()
      }
    } else {
      callback()
    }
  },

  // 手机号码的验证
  validatePhone (rule, value, callback) {
    if (!isEmpty(value)) {
      if (!phoneReg.test(value)) {
        callback(new Error('手机格式不正确'))
      } else {
        callback()
      }
    } else {
      callback()
    }
  },

  // 手机号码+邮箱的验证
  validatePhoneEmail (rule, value, callback) {
    if (!isEmpty(value)) {
      if (value.indexOf('@') != -1) {
        if (!emailReg.test(value)) {
          callback(new Error('邮箱格式不正确'))
        } else {
          callback()
        }
      } else {
        if (!phoneReg.test(value)) {
          callback(new Error('手机格式不正确'))
        } else {
          callback()
        }
      }
    } else {
      callback()
    }
  },

  // 协议编码的验证
  protocolCode (rule, value, callback) {
    if (!isEmpty(value)) {
      if (!protocolCodeReg.test(value)) {
        callback(new Error('协议编号格式不正确'))
      } else {
        callback()
      }
    } else {
      callback()
    }
  },

  // 身份证的验证规则
  ID (rule, value, callback) {
    if (!isEmpty(value)) {
      if (!regId.test(value)) {
        callback(new Error('请输入正确的二代身份证号码'))
      } else {
        callback()
      }
    } else {
      callback()
    }
  },

  // 统一社会信用代码 工商营业执照注册号
  USCC (rule, value, callback) {
    if (!isEmpty(value)) {
      if (!uscc.test(value)) {
        callback(new Error('请输入13、15、18位字母或数字'))
      } else {
        callback()
      }
    } else {
      callback()
    }
  },
  /**
   * 下拉框输入名字过滤数据
   * @param inputValue
   * @param option
   * @returns {boolean}
   */
  filterOption (inputValue, option) {
    if (isEmpty(inputValue)) {
      return true
    }
    return (
      option.componentOptions.children[0].text
        .toUpperCase()
        .indexOf(inputValue.toUpperCase()) >= 0
    )
  },
  checkPassWord (rule, value, callback) {
    // 0： 表示第一个级别 1：表示第二个级别 2：表示第三个级别
    // 3： 表示第四个级别 4：表示第五个级别
    let modes = 0
    let level = rule.level || 1
    let message = rule.message || '密码级别不够，要求的级别为：' + level
    if (/\d/.test(value)) {
      // 如果用户输入的密码 包含了数字
      modes++
    }
    if (/[a-z]/.test(value)) {
      // 如果用户输入的密码 包含了小写的a到z
      modes++
    }
    if (/[A-Z]/.test(value)) {
      // 如果用户输入的密码 包含了大写的A到Z
      modes++
    }
    if (/\W/.test(value)) {
      // 如果是非数字 字母 下划线
      modes++
    }
    if (modes < level) {
      callback(new Error(message))
    } else {
      callback()
    }
  }
}

validators.install = function fn (Vue) {
  Vue.prototype.validators = validators
}
export default validators
